package com.wt.demo;

import java.text.SimpleDateFormat;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @description
 * @author: wangtao
 * @date:14:52 2019/6/19
 * @email:386427665@qq.com
 */
public class ThreadLocalGCDemo {

    static volatile ThreadLocal<SimpleDateFormat> tl = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected void finalize() throws Throwable {
            System.out.println(this.toString() + " is GC");
        }
    };

    static volatile CountDownLatch cdl = new CountDownLatch(10);

    static class ParseDate implements Runnable {

        @Override
        public void run() {
            try {
                if (tl.get() == null) {
                    tl.set(new SimpleDateFormat("yyyy-MM-dd"));
                    System.out.println("create SimpleDateFormat");
                } else {
                    tl.get().parse("2019-06-19");
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                cdl.countDown();
            }
        }

        @Override
        protected void finalize() throws Throwable {
            System.out.println(this.toString() + "is GC");
        }

    }

    public static void main(String[] args) throws InterruptedException {
        System.out.println(tl);
        ExecutorService exec = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 10; i++) {
            exec.execute(new ParseDate());
        }
        cdl.await();
        Thread.sleep(1000);
        System.out.println("mission complete");
        System.gc();
        System.out.println("first GC complete");
        System.out.println("sleep 3 second");
        Thread.sleep(3000);
        //在设置ThreadLocal的时候会清除ThreadLocalMap中的无效对象
        tl = new ThreadLocal<>();
        cdl = new CountDownLatch(10);
        for (int i = 0; i < 10; i++) {
            exec.execute(new ParseDate());
        }
        cdl.await();
        Thread.sleep(1000);
        System.out.println("second GC begin");
        System.gc();
        System.out.println("second GC complete");
        Thread.sleep(3000);
    }
}
